import json

from typing import Union, List
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.db.models.query import QuerySet

from product import models
import product.utils.work_with_stripe as work_with_stripe
import product.utils.order as order


class ProductUtils:
    """ Инструменты для обработки запроса связанного с продуктом """

    def get_template_for_displaying_single_product(
            self, request: WSGIRequest, pk: int) -> HttpResponse:
        """ Возвращаем шаблон для отображения отдельного продукта """

        product = models.Product.objects.get(pk=pk)
        context = {'product': product,
                   'show_buy_button': True}
        return render(request, 'product/single_product.html', context)


    def get_template_for_displaying_list_of_products(
            self, request: WSGIRequest) -> HttpResponse:
        """ Возвращаем шаблон для отображения списка продуктов """

        list_of_products = models.Product.objects.all()
        context = {'list_of_products': list_of_products}
        return render(request, 'product/list_of_products.html', context)


    def convert_rubles_to_cents(self, price: float) -> float:
        """ Переводим рубли в центы """

        dollar_rate = 73
        return int(price / dollar_rate * 100)


    def get_value_of_field_of_all_products(
            self,
            list_of_products: QuerySet,
            field_name: str,
            data_type) -> List[str]:
        """ Получаем значение поля всех продуктов """

        return [data_type(product[field_name]) for product in list_of_products]


class BuyUtils:
    """ Инструменты для обработки запроса на покупку чего-то """

    def get_session_to_pay_for_product(
            self,
            pk: int) -> JsonResponse:
        """ Получаем сессию для оплаты продукта """

        buying_product = models.Product.objects.get(id=pk)
        checkout_session_id = work_with_stripe.WorkWithApiStripe().create_session_to_pay_for_selected_products(
            product=buying_product
        )
        return JsonResponse(checkout_session_id)


    def perform_necessary_action(
            self,
            request: WSGIRequest,
            pk: int) -> JsonResponse:

        if 'session_to_pay_for_product' in request.GET:
            return self.get_session_to_pay_for_product(pk)
        else:
            message = f'Полученные параметры не обрабатываются: {request.GET}'
            raise ValueError(message)



class CartUtils:
    """ Инструменты для обработки запросов связанных с корзиной """

    def add_new_product_to_order(
            self,
            request: WSGIRequest) -> JsonResponse:
        """ Добавляем новый продукт в заказ """

        data = json.loads(request.body)
        product_id = data['product_id']
        last_order = order.OrderUtils().get_last_order()
        product = models.Product.objects.get(pk=product_id)
        response = order.OrderUtils().add_product_to_order(last_order, product)
        return JsonResponse(response)


    def display_order(self, request: WSGIRequest) -> HttpResponse:
        """ Отображаем заказ """

        order_products = order.OrderUtils().get_order_products()
        order_amount = order.OrderUtils().get_order_amount()
        order_quantity_of_products = order.OrderUtils().get_quantity_of_order_products()
        context = {
            'order_products': order_products,
            'order_amount': order_amount,
            'order_quantity_of_products': order_quantity_of_products,
        }
        return render(request, 'product/cart.html', context)


    def pay_for_order(self) -> JsonResponse:
        """ Оплачиваем заказ """

        order_products = order.OrderUtils().get_order_products(type_of_dict=False)
        tax_rates = [
            order.TaxRateType(
                display_name='ST',
                percentage=7
            ),
            order.TaxRateType(
                display_name='T',
                percentage=5
            )
        ]
        checkout_session_id = work_with_stripe.WorkWithApiStripe().create_session_to_pay_for_selected_products(
            list_of_products=order_products,
            discount=30,
            tax_rates=tax_rates
        )
        return JsonResponse(checkout_session_id)


    def perform_necessary_action(
            self,
            request: WSGIRequest) -> Union[HttpResponse, JsonResponse]:

        if 'add_product_to_cart' in request.GET:
            return self.add_new_product_to_order(request)
        elif 'pay_for_order' in request.GET:
            return self.pay_for_order()
        else:
            message = f'Полученные параметры не обрабатываются: {request.GET}'
            raise ValueError(message)


    def get_necessary_information(
            self,
            request: WSGIRequest) -> Union[HttpResponse, JsonResponse]:
        """ Получаем необходимую информацию """

        if 'display_cart' in request.GET:
            return self.display_order(request)
        else:
            message = f'Полученные параметры не обрабатываются: {request.GET}'
            raise ValueError(message)
